﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace EHR18
{
    public static class BinaryUtil
    {
        /// <summary>
        /// 把字节数组转换成字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string ByteToHex(this byte[] data)
        {
            string[] hexs = Array.ConvertAll<byte, string>(data, (b) => b.ToString("X2"));
            return String.Join(" ", hexs);
        }

        /// <summary>
        /// 把字符串数组转换成字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] HexToByte(this string hexString)
        {
            string[] hexSplit = hexString.Split(' ');
            return Array.ConvertAll<string, byte>(hexSplit, (s) => byte.Parse(s, NumberStyles.HexNumber));
        }

        /// <summary>
        /// 截取字节
        /// </summary>
        /// <param name="data"></param>
        /// <param name="startindex"></param>
        /// <param name="length"></param>
        /// <param name="isreverseorder"></param>
        /// <returns></returns>
        public static byte[] SubBytes(this byte[] data, int startindex, int length, bool isreverseorder)
        {
            byte[] tmp = new byte[length];
            Array.Copy(data, startindex, tmp, 0, tmp.Length);
            if (isreverseorder) tmp = Reverse(tmp);
            return tmp;
        }

        /// <summary>
        /// 翻转字节
        /// </summary>
        /// <param name="reverse"></param>
        /// <returns></returns>
        private static byte[] Reverse(this byte[] reverse)
        {
            Array.Reverse(reverse);
            return reverse;
        }

        /// <summary>
        /// 数字转换成十六进制的BCD
        /// </summary>
        /// <param name="dig"></param>
        /// <returns></returns>
        public static byte Dig2HexBCD(this int ivalue)
        {
            //Debug.Assert (iDigNumber>=0 && iDigNumber<=8);
            int dwRet = 0;
            int dwTmp = 0;
            for (int i = 0; i < 8; i++)
            {
                dwTmp = ivalue % 10;
                ivalue /= 10;
                dwTmp <<= i * 4;
                dwRet |= dwTmp;
            }
            return (byte)dwRet;
        }

        /// <summary>
        /// 十六进制BCD转换成数字
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        public static int HexBCD2Dig(byte hex)
        {
            return (int)Convert.ToByte(Convert.ToString(hex, 16));
        }

        /// <summary>
        /// 转成二进制字符串
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public static string ByteToBinary(this byte b)
        {
            return System.Convert.ToString(b, 2).PadLeft(8, '0');
        }
        /// <summary>
        /// 将Ushort数组转换成字符串
        /// </summary>
        /// <param name="array"></param>
        /// <param name="BigEndian">是否为大端字节序（PLC可能是小端的）</param>
        /// <returns></returns>
        public static string UshortsToString(this ushort[] array, bool BigEndian = false)
        {
            return Encoding.ASCII.GetString(UshortsToBytes(array, BigEndian));
        }

        /// <summary>
        /// 将Ushort数组转换成二进制数组
        /// </summary>
        /// <param name="array"></param>
        /// <param name="BigEndian">是否为大端字节序（PLC可能是小端的）</param>
        /// <returns></returns>
        public static byte[] UshortsToBytes(this ushort[] array,bool BigEndian=false)
        {
            List<byte> bytes = new List<byte>();
            foreach(var s in array)
            {
               byte[] byteArray= UshortToBytes(s, BigEndian);
               bytes.AddRange(byteArray);
            }
            return bytes.ToArray();
        }
        /// <summary>
        /// 将Ushort数组转换成二进制
        /// </summary>
        /// <param name="array"></param>
        /// <param name="BigEndian">是否为大端字节序（PLC可能是小端的）</param>
        /// <returns></returns>
        public static byte[] UshortToBytes(ushort s,bool bigEndian)
        {
            byte[] bytes = BitConverter.GetBytes(s);
            if (bigEndian)
                Array.Reverse(bytes);
            return bytes;
        }
        /// <summary>
        /// BCD bytes 转成整数
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static int BCDBytesToDig(byte[] bytes)
        {
            string[] hexs = Array.ConvertAll<byte, string>(bytes, (b) => b.ToString("X"));
            return int.Parse(string.Join("", hexs));
        }
        /// <summary>
        /// BCD码转浮点数
        /// </summary>
        /// <param name="bytes">输入数据</param>
        /// <param name="nPoint">小数位数</param>
        /// <returns></returns>
        public static double BCDBytesToDouble(byte[] bytes, int nPoint)
        {
           return BCDBytesToDig(bytes) * Math.Pow(10, -1 * nPoint);
        }
        /// <summary>
        /// UShort BCD数组直接转换成浮点数
        /// </summary>
        /// <param name="datas">输入数据</param>
        /// <param name="nPoint">小数位数</param>
        /// <param name="BigEndian">是否按照大端排列</param>
        /// <returns></returns>
        public static double BCDUShortsToDouble(ushort[] datas, int nPoint=0,bool BigEndian=false)
        {
            return BCDBytesToDouble(UshortsToBytes(datas, BigEndian), nPoint);
        }
    }
}